Public Enum CardSuit

    Hearts = 1
    Spades = 2
    Clubs = 3
    Diamonds = 4
    Red = 991
    Black = 992
End Enum

Public Enum CardValue

    Ace = 1
    Two = 2
    Three = 3
    Four = 4
    Five = 5
    Six = 6
    Seven = 7
    Eight = 8
    Nine = 9
    Ten = 10
    Jack = 11
    Queen = 12
    King = 13
    Joker = 999
End Enum

Public Enum CardBackColor

    Red = 1
    Blue = 2
End Enum

Partial Public Class Card

    Private _Suit As CardSuit
    Private _Value As CardValue

    Sub New(ByVal Suit As CardSuit, ByVal Value As CardValue)
        Me.Suit = Suit
        Me.Value = Value
    End Sub
    Public Property Value() As CardValue
        Get
            Return _Value
        End Get
        Set(ByVal value As CardValue)
            _Value = value
        End Set
    End Property

    Public Property Suit() As CardSuit
        Get
            Return _Suit
        End Get
        Set(ByVal value As CardSuit)
            _Suit = value
        End Set
    End Property

    Public Overrides Function ToString() As String

        Return _Value.ToString + " of " + _Suit.ToString
    End Function
End Class

Partial Public Class Deck

    Private _HasJokers As Boolean = False
    Private _SmallDeck As Boolean = False
    Private _Cards As List(Of Card)

    Public ReadOnly Property HasJokers() As Boolean
        Get
            Return _HasJokers
        End Get
    End Property

    Public ReadOnly Property SmallDeck() As Boolean
        Get
            Return _SmallDeck
        End Get
    End Property

    Public Property Cards() As List(Of Card)
        Get
            Return _Cards
        End Get
        Set(ByVal value As List(Of Card))
            _Cards = value
        End Set
    End Property

    Sub New(Optional ByVal Shuffle As Boolean = False, Optional ByVal HasJokers As Boolean = False, Optional ByVal SmallDeck As Boolean = False)
        _Cards = New List(Of Card)
        FillDeck(HasJokers, SmallDeck)

        Me._HasJokers = HasJokers
        Me._SmallDeck = SmallDeck

        If Shuffle Then Me.Shuffle()
    End Sub

    Private Sub FillDeck(ByVal HasJokers As Boolean, ByVal SmallDeck As Boolean)

        'with a smalldeck, cards start at 7, otherwise cards start at 2
        Dim myLowestCard As CardValue = IIf(SmallDeck, CardValue.Seven, CardValue.Two)

        For x As CardSuit = CardSuit.Hearts To CardSuit.Diamonds
            'always add Ace to the deck
            Me._Cards.Add(New Card(x, CardValue.Ace))
            'add cards from 2 or 7
            For y As CardValue = myLowestCard To CardValue.King
                Me._Cards.Add(New Card(x, y))
            Next
        Next

        'add jokers as needed
        If HasJokers Then
            _Cards.Add(New Card(CardSuit.Black, CardValue.Joker))
            _Cards.Add(New Card(CardSuit.Red, CardValue.Joker))
        End If
    End Sub

    Public Sub Shuffle()

        Dim myCards As New List(Of Card)
        Dim rnd As New Random
        Dim rndCard As Integer

        'run till all cards are used
        Do While _Cards.Count > 0
            'pick a random card
            rndCard = rnd.Next(0, _Cards.Count)
            'add card to new list
            myCards.Add(_Cards.Item(rndCard))
            'remove card from old list
            _Cards.RemoveAt(rndCard)
        Loop

        'copy new list to old list
        _Cards = myCards
    End Sub

    Public Sub Deal(ByRef Hand As Hand, ByVal Amount As Byte)

        For x As Integer = 1 To Amount
            'add card to hand
            Hand.Cards.Add(_Cards.Item(0))
            'remove card from deck
            _Cards.RemoveAt(0)
        Next
    End Sub
End Class

Partial Public Class Hand

    Private _Cards As List(Of Card)

    Sub New()
        _Cards = New List(Of Card)
    End Sub
    Public Property Cards() As List(Of Card)
        Get
            Return _Cards
        End Get
        Set(ByVal value As List(Of Card))
            _Cards = value
        End Set
    End Property
End Class

Partial Public Class CardsUtils

    Public Shared Sub CheckCardString(ByRef myCardString As String)

        If myCardString.Length = 2 Then

            Dim myTempString As String = String.Empty

            Select Case myCardString.Substring(0, 1)
                Case "N"
                    myTempString = "Joker"
                Case "2"
                    myTempString = "Two"
                Case "3"
                    myTempString = "Three"
                Case "4"
                    myTempString = "Four"
                Case "5"
                    myTempString = "Five"
                Case "6"
                    myTempString = "Six"
                Case "7"
                    myTempString = "Seven"
                Case "8"
                    myTempString = "Eight"
                Case "9"
                    myTempString = "Nine"
                Case "T"
                    myTempString = "Ten"
                Case "J"
                    myTempString = "Jack"
                Case "Q"
                    myTempString = "Queen"
                Case "K"
                    myTempString = "King"
                Case "A"
                    myTempString = "Ace"
            End Select

            myTempString += " of "

            Select Case myCardString.Substring(1, 1)
                Case "h"
                    myTempString += "Hearts"
                Case "s"
                    myTempString += "Spades"
                Case "c"
                    myTempString += "Clubs"
                Case "d"
                    myTempString += "Diamonds"
                Case "r"
                    myTempString += "Red"
                Case "b"
                    myTempString += "Black"
            End Select

            myCardString = myTempString
        End If
    End Sub

    Public Shared Function GetCardValueString(ByVal myCardString As String) As String

        Return myCardString.Split(" of ")(0)
    End Function

    Public Shared Function GetCardSuitString(ByVal myCardString As String) As String

        Return myCardString.Split(" of ")(2)
    End Function
End Class